#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "pqc_sdf_client.h"
static const char *puiKeypasswd = NULL;

int PrintData(const char *itemName, unsigned char *sourceData, unsigned int dataLength, unsigned int rowCount)
{
	int i, j;

	if ((sourceData == NULL) || (rowCount == 0) || (dataLength == 0))
		return -1;

	if (itemName != NULL)
		printf("%s[%d]:\n", itemName, dataLength);

	for (i = 0; i<(int)(dataLength / rowCount); i++)
	{
		printf("%08x  ", i*rowCount);
		for (j = 0; j<(int)rowCount; j++)
		{
			printf("%02x ", *(sourceData + i*rowCount + j));
		}
		printf("\n");
	}
	if (!(dataLength%rowCount))
		return 0;

	printf("%08x  ", (dataLength / rowCount)*rowCount);
	for (j = 0; j<(int)(dataLength%rowCount); j++)
	{
		printf("%02x ", *(sourceData + (dataLength / rowCount)*rowCount + j));
	}
	printf("\n");
	return 0;
}



void DeviceMgrFuncTest() {
	int rn = 0;

	void *hDeviceHandle = NULL;
	void *hSessionHandle = NULL;
	DEVICEINFO devInfo;
	unsigned char recvData[4096];

	rn = SDF_OpenDevice(&hDeviceHandle);
	if (rn == 0) {
		printf("打开设备成功\n");
	}
	else {
		printf("打开设备失败: %d\n", rn);
		return;
	}

	rn = SDF_OpenSession(hDeviceHandle, &hSessionHandle);
	if (rn == 0) {
		printf("打开会话成功\n");
	}
	else {
		printf("打开会话失败\n");
		return;
	}

	rn = SDF_GetDeviceInfo(hSessionHandle, &devInfo);
	if (rn == 0) {
		printf("获取设备信息成功，%s\n", devInfo.IssuerName);
	}
	else {
		printf("获取设备信息失败\n");
	}

	rn = SDF_GenerateRandom(hSessionHandle, 64, recvData);
	if (rn == 0) {
		int i = 0;
		printf("获取随机数成功：\n");
		for (i = 0; i < 64; i++) {
			printf("%02x", recvData[i]);
		}
		printf("\n");
	}
	else {
		printf("获取随机数失败\n");
	}

	rn = SDF_CloseSession(hSessionHandle);
	if (rn == 0) {
		printf("关闭会话成功\n");
	}
	else {
		printf("关闭会话失败\n");
	}

	rn = SDF_CloseDevice(hDeviceHandle);
	if (rn == 0) {
		printf("关闭设备成功\n");
	}
	else {
		printf("关闭设备失败\n");
	}
	printf("\n");
}

void AsymKeyMgrFuncTest() {
	int rn = 0;
	void *hDeviceHandle = NULL;
	void *hSessionHandle = NULL;

	rn = SDF_OpenDevice(&hDeviceHandle);
	if (rn == 0) {
		printf("打开设备成功\n");
	}
	else {
		printf("打开设备失败\n");
		return;
	}

	rn = SDF_OpenSession(hDeviceHandle, &hSessionHandle);
	if (rn == 0) {
		printf("打开会话成功\n");
	}
	else {
		printf("打开会话失败\n");
		return;
	}


	while (true)
	{
		int rt = 0;
		int choice;
		printf("<-----------------------非对称密钥管理------------------------->\n");
		printf(" 1|导出RSA签名公钥\n");
		printf(" 2|导出RSA加密公钥\n");
		printf(" 3|产生RSA密钥对\n");
		printf(" 4|导出ECC签名公钥\n");
		printf(" 5|导出ECC加密公钥\n");
		printf(" 6|产生ECC密钥对\n");
		printf(" 0|return\n");
		printf("<----------------------------------------------------->\n");
		printf("请输入测试功能编号：");
		scanf("%d", &choice);

		switch (choice)
		{
		case 1: {
			printf("请输入要导出的密钥号:\n");
			int keyIndex = 0;
			scanf("%d", &keyIndex);
			RSArefPublicKey  pubKey;
	

			int rv = SDF_ExportSignPublicKey_RSA(hSessionHandle, keyIndex, &pubKey);
			if (rv != SDR_OK)
			{
				printf("导出签名RSA公钥错误，错误码[0x%08x]\n", rv);
			}
			else
			{
				int pukLen = sizeof(RSArefPublicKey);
				printf("导出签名RSA公钥成功\n");
				PrintData("PUBLICKEY", (unsigned char *)&pubKey, pukLen, 16);
				printf("\n");
			}
			break;
		}
		case 2: {
			printf("请输入要导出的密钥号:\n");
			int keyIndex = 0;
			scanf("%d", &keyIndex);
			RSArefPublicKey  pubKey;

			int rv = SDF_ExportEncPublicKey_RSA(hSessionHandle, keyIndex, &pubKey);
			if (rv != SDR_OK)
			{
				printf("导出加密RSA公钥错误，错误码[0x%08x]\n", rv);
			}
			else
			{
				int pukLen = sizeof(RSArefPublicKey);
				printf("导出加密RSA公钥成功\n");
				PrintData("PUBLICKEY", (unsigned char *)&pubKey, pukLen, 16);
				printf("\n");
			}
			break;
		}
		case 3: {
			RSArefPublicKey  pubKey;
			RSArefPrivateKey prik;
			int rv = SDF_GenerateKeyPair_RSA(hSessionHandle, 1024, &pubKey, &prik);
			if (rv == 0) {
				printf("产生RSA密钥对成功: \n");
				PrintData("PUBLICKEY", (unsigned char *)&pubKey, sizeof(RSArefPublicKey), 16);
				PrintData("PRIVATEKEY", (unsigned char *)&prik, sizeof(RSArefPrivateKey), 16);
			}
			else {
				printf("产生ECC密钥对失败: %08x\n",rv);
			}
			break;
		}
		case 4: {
			printf("请输入要导出的密钥号:\n");
			int keyIndex = 0;
			scanf("%d", &keyIndex);
			ECCrefPublicKey  pubKey;

			int rv = SDF_ExportSignPublicKey_ECC(hSessionHandle, keyIndex, &pubKey);
			if (rv != SDR_OK)
			{
				printf("导出签名ECC公钥错误，错误码[0x%08x]\n", rv);
			}
			else
			{
				int pukLen = sizeof(ECCrefPublicKey);
				printf("导出签名ECC公钥成功\n");
				PrintData("PUBLICKEY", (unsigned char *)&pubKey, pukLen, 16);
				printf("\n");
			}
			break;
		}
		case 5: {
			printf("请输入要导出的密钥号:");
			ECCrefPublicKey  pubKey;
			int keyIndex = 0;
			scanf("%d", &keyIndex);

			int rv = SDF_ExportEncPublicKey_ECC(hSessionHandle, keyIndex, &pubKey);
			if (rv != SDR_OK)
			{
				printf("导出签名ECC公钥错误，错误码[0x%08x]\n", rv);
			}
			else
			{
				int pukLen = sizeof(ECCrefPublicKey);
				printf("导出签名ECC公钥成功\n");
				PrintData("PUBLICKEY", (unsigned char *)&pubKey, pukLen, 16);
				printf("\n");
			}
			break;
		}
		case 6: {
			ECCrefPublicKey  pubKey;
			ECCrefPrivateKey prik;
			int rv =  SDF_GenerateKeyPair_ECC(hSessionHandle, SGD_SM2_1, 256, &pubKey, &prik);
			if (rv == 0) {
				printf("产生ECC密钥对成功: \n");
				PrintData("PUBLICKEY", (unsigned char *)&pubKey, sizeof(ECCrefPublicKey), 16);
				PrintData("PRIVATEKEY", (unsigned char *)&prik, sizeof(ECCrefPrivateKey), 16);
			}
			else {
				printf("产生ECC密钥对失败: %08x\n", rv);
			}
			break;
		}
		case 0:
		{
			rt = 1;
			break;
		}
		default:
			printf("err input.\n");
			break;
		}

		if (rt)
			break;

	}

	rn = SDF_CloseSession(hSessionHandle);
	if (rn == 0) {
		printf("关闭会话成功\n");
	}
	else {
		printf("关闭会话失败\n");
	}

	rn = SDF_CloseDevice(hDeviceHandle);
	if (rn == 0) {
		printf("关闭设备成功\n");
	}
	else {
		printf("关闭设备失败\n");
	}
	printf("\n");
}

void SymKeyMgrFuncTest() {
	int rt = 0;
	void *hDeviceHandle = NULL;
	void *hSessionHandle = NULL;

	int rn = SDF_OpenDevice(&hDeviceHandle);
	if (rn == 0) {
		printf("打开设备成功\n");
	}
	else {
		printf("打开设备失败\n");
		return;
	}

	rn = SDF_OpenSession(hDeviceHandle, &hSessionHandle);
	if (rn == 0) {
		printf("打开会话成功\n");
	}
	else {
		printf("打开会话失败\n");
		return;
	}

	int keyIndex = 1;
    rn = SDF_GetPrivateKeyAccessRight(hSessionHandle, keyIndex, (unsigned char *)puiKeypasswd, 8);
    if (rn != 0) {
        printf("获取私钥访问权限失败 %08x\n", rn);
    }
    else {
        printf ("获取私钥访问权限成功\n");
    }

	while (true)
	{
		printf("<-----------------------会话密钥管理------------------------->\n");
		printf(" 1|生成会话密钥并用内部RSA公钥加密输出\n");
		printf(" 2|生成会话密钥并用外部RSA公钥加密输出\n");
		printf(" 3|导入会话密钥并用内部RSA私钥解密\n");
		printf(" 4|基于RSA算法的数字信封转换\n");
		printf(" 5|生成会话密钥并用内部ECC公钥加密输出\n");
		printf(" 6|生成会话密钥并用外部ECC公钥加密输出\n");
		printf(" 7|导入会话密钥并用内部ECC私钥解密\n");
		printf(" 8|基于ECC算法的数字信封转换\n");
		printf(" 9|生成会话密钥并用密钥加密密钥加密输出\n");
		printf(" 10|导入会话密钥并用密钥加密密钥解密\n");
		printf(" 0|return\n");
		printf("<----------------------------------------------------->\n");
		printf("请输入测试功能编号：");

		int choice;
		scanf("%d", &choice);

		switch (choice)
		{
		case 1: {
			void* hKeyHandle = NULL;
			unsigned char pucKey[1024] = {0};
			unsigned int keyLen;

			int result = SDF_GenerateKeyWithIPK_RSA(hSessionHandle, keyIndex, 128, pucKey, &keyLen, &hKeyHandle);
			if (result == 0) {
				printf("生成会话密钥并用内部RSA公钥加密输出成功: ");
				PrintData("加密后密钥为", pucKey, keyLen, 16);
				printf("密钥句柄为 %ld\n", (long)hKeyHandle);

				
				result = SDF_DestroyKey(hSessionHandle, hKeyHandle);
				if (result == 0){
					printf("会话密钥销毁成功\n");
				}
				else {
					printf("密钥销毁失败: %08x\n", result);
				}
			}
			else {
				printf("生成会话密钥并用内部RSA公钥加密输出失败: %08x\n", result);
			}
			break;
		}
		case 2: {
			RSArefPublicKey pubk;
			RSArefPrivateKey prik;
			int result = SDF_GenerateKeyPair_RSA(hSessionHandle, 1024, &pubk, &prik);
			if (result == 0) {
				printf("产生RSA密钥对成功\n");
			}
			else {
				printf("产生RSA密钥对失败: %08x", result);
			}


			void* hKeyHandle;
			unsigned char ucKey[4096] = {0};
			unsigned int ucKeyLen;
			result = SDF_GenerateKeyWithEPK_RSA(hSessionHandle, 128, &pubk, ucKey,&ucKeyLen, &hKeyHandle);
			if (result != 0) {
				printf("生成会话密钥并用外部RSA公钥加密输出失败: %08x\n", result);
			}
			else {
				printf("生成会话密钥并用外部RSA公钥加密输出成功: ");
				PrintData("加密后密钥为", ucKey, ucKeyLen, 16);

				result = SDF_DestroyKey(hSessionHandle, hKeyHandle);
				if (result == 0){
					printf("会话密钥销毁成功\n");
				}
				else {
					printf("密钥销毁失败: %08x\n", result);
				}
			}
			break;
		}
		case 3: {
			void* hKeyHandle = NULL;
			unsigned char ucKey[4096] = { 0 };
			unsigned int ucKeyLen;
			int result = SDF_GenerateKeyWithIPK_RSA(hSessionHandle, keyIndex, 128, ucKey, &ucKeyLen, &hKeyHandle);
			if (result == 0) {
				printf("生成会话密钥并用内部RSA公钥加密输出成功: ");
				PrintData("加密后密钥为", ucKey, ucKeyLen, 16);

				result = SDF_DestroyKey(hSessionHandle, hKeyHandle);
				if (result == 0){
					printf("会话密钥销毁成功\n");
				}
				else {
					printf("密钥销毁失败: %08x\n", result);
				}
			}
			else {
				printf("生成会话密钥并用内部ECC公钥加密输出失败: %08x\n" , result);
			}

			hKeyHandle = NULL;
			result = SDF_ImportKeyWithISK_RSA(hSessionHandle, keyIndex, ucKey, ucKeyLen, &hKeyHandle);
			if (result != 0) {
				printf("导入会话密钥并用内部RSA私钥解密失败: %08x\n" , result);
			}
			else {
				printf("导入会话密钥并用内部RSA私钥解密成功\n");
				result = SDF_DestroyKey(hSessionHandle, hKeyHandle);
				if(result == 0) {
					printf("会话密钥销毁成功\n");
				}
				else {
					printf("会话密钥销毁失败 %08x\n", result);
				}
			}
			break;
		}
		case 4: {
			void* hKeyHandle = NULL;
			unsigned char ucKey[4096] = { 0 };
			unsigned int ucKeyLen;
			int result = SDF_GenerateKeyWithIPK_RSA(hSessionHandle, keyIndex, 128, ucKey, &ucKeyLen, &hKeyHandle);
			if (result == 0) {
				printf("生成会话密钥并用内部RSA公钥加密输出成功: ");
				PrintData("加密后密钥为", ucKey, ucKeyLen, 16);

				result = SDF_DestroyKey(hSessionHandle, hKeyHandle);
				if (result == 0){
					printf("会话密钥销毁成功\n");
				}
				else {
					printf("密钥销毁失败: %08x\n", result);
				}
			}
			else {
				printf("生成会话密钥并用内部ECC公钥加密输出失败: %08x" ,result);
			}


			RSArefPublicKey pubk;
			RSArefPrivateKey prik;
			result = SDF_GenerateKeyPair_RSA(hSessionHandle, 1024, &pubk, &prik);
			if (result == 0) {
				printf("产生RSA密钥对成功");
			}
			else {
				printf("产生RSA密钥对失败: %08x" , result);
			}


			unsigned char deData[4096] = { 0 };
			unsigned int deLen;
			result = SDF_ExchangeDigitEnvelopeBaseOnRSA(hSessionHandle, keyIndex, &pubk, ucKey, ucKeyLen, deData,&deLen);
			if (result != 0) {
				printf("基于RSA算法的数字信封转换失败: %08x" ,result);
			}
			else {
				printf("基于RSA算法的数字信封转换成功: \n");
				PrintData("转换后密文为", deData, deLen, 16);
			}
			break;
		}
		case 5: {
			void* hKeyHandle = NULL;
			unsigned char eccEnc[4096] = {0};
			int result = SDF_GenerateKeyWithIPK_ECC(hSessionHandle, keyIndex, 128, (ECCCipher*)eccEnc, &hKeyHandle);
			if (result == 0) {
				printf("生成会话密钥并用内部ECC公钥加密输出成功: \n");
				PrintData("转换后密文为", eccEnc, sizeof(ECCCipher), 16);

				result = SDF_DestroyKey(hSessionHandle, hKeyHandle);
				if (result == 0){
					printf("会话密钥销毁成功\n");
				}
				else {
					printf("密钥销毁失败: %08x\n", result);
				}
			}
			else {
				printf("生成会话密钥并用内部ECC公钥加密输出失败: %08x" , result);
			}
			break;
		}
		case 6: {
			ECCrefPublicKey  pubKey;
			ECCrefPrivateKey prik;
			int rv = SDF_GenerateKeyPair_ECC(hSessionHandle, SGD_SM2_1, 256, &pubKey, &prik);
			if (rv == 0) {
				printf("产生ECC密钥对成功: \n");
			}
			else {
				printf("产生ECC密钥对失败: %08x\n", rv);
			}

			void* hKeyHandle = NULL;
			unsigned char eccEnc[4096] = { 0 };
			int result = SDF_GenerateKeyWithEPK_ECC(hSessionHandle, 128, SGD_SM2_3, &pubKey, (ECCCipher*)eccEnc, &hKeyHandle);
			if (result != 0) {
				printf("生成会话密钥并用外部ECC公钥加密输出失败: %08x\n" , result);
			}
			else {
				printf("生成会话密钥并用外部ECC公钥加密输出成功: ");
				PrintData("加密后密钥为", eccEnc, 292, 16);

				result = SDF_DestroyKey(hSessionHandle, hKeyHandle);
				if (result == 0){
					printf("会话密钥销毁成功\n");
				}
				else {
					printf("密钥销毁失败： %08x\n", result);
				}
			}
			break;
		}
		case 7: {
			void* hKeyHandle = NULL;
			unsigned char eccEnc[4096] = { 0 };
			int result = SDF_GenerateKeyWithIPK_ECC(hSessionHandle, keyIndex, 16, (ECCCipher*)eccEnc, &hKeyHandle);
			if (result == 0) {
				printf("生成会话密钥并用内部ECC公钥加密输出成功: \n");
				PrintData("加密后密钥为", eccEnc, 300, 16);

				result = SDF_DestroyKey(hSessionHandle, hKeyHandle);
				if (result == 0){
					printf("会话密钥销毁成功\n");
				}
				else {
					printf("密钥销毁失败： %08x\n", result);
				}
			}
			else {
				printf("生成会话密钥并用内部ECC公钥加密输出失败: %08x" , result);
			}

			hKeyHandle = NULL;
			result = SDF_ImportKeyWithISK_ECC(hSessionHandle, keyIndex, (ECCCipher*)eccEnc, &hKeyHandle);
			if (result != 0) {
				printf("导入会话密钥并用内部ECC私钥解密失败: %08x\n" , result);
			}
			else {
				printf("导入会话密钥并用内部ECC私钥解密成功: \n");

				result = SDF_DestroyKey(hSessionHandle, hKeyHandle);
				if (result == 0){
					printf("会话密钥销毁成功\n");
				}
				else {
					printf("密钥销毁失败: %08x\n", result);
				}
			}
			break;
		}
		case 8: {
			void* hKeyHandle = NULL;
			unsigned char eccEnc[4096] = { 0 };
			int result = SDF_GenerateKeyWithIPK_ECC(hSessionHandle, keyIndex, 16, (ECCCipher*)eccEnc, &hKeyHandle);
			if (result == 0) {
				printf("生成会话密钥并用内部ECC公钥加密输出成功: \n");
				PrintData("加密后密钥为", eccEnc, sizeof(ECCCipher), 16);


				result = SDF_DestroyKey(hSessionHandle, hKeyHandle);
				if (result == 0){
					printf("会话密钥销毁成功\n");
				}
				else {
					printf("密钥销毁失败: %08x\n", result);
				}
			}
			else {
				printf("生成会话密钥并用内部ECC公钥加密输出失败: %08x" , result);
			}


			ECCrefPublicKey  pubKey;
			ECCrefPrivateKey prik;
			int rv = SDF_GenerateKeyPair_ECC(hSessionHandle, SGD_SM2_1, 256, &pubKey, &prik);
			if (rv == 0) {
				printf("产生ECC密钥对成功: \n");
				PrintData("PUBLICKEY", (unsigned char *)&pubKey, sizeof(ECCrefPublicKey), 16);
				PrintData("PRIVATEKEY", (unsigned char *)&prik, sizeof(ECCrefPrivateKey), 16);
			}
			else {
				printf("产生ECC密钥对失败: %08x\n" , rv);
			}


			unsigned char eccEnc2[4096] = { 0 };
			result = SDF_ExchangeDigitEnvelopeBaseOnECC(hSessionHandle, keyIndex, SGD_SM2_3, &pubKey, (ECCCipher*)eccEnc, (ECCCipher*)eccEnc2);
			if (result != 0) {
				printf("基于ECC算法的数字信封转换失败: %08x\n" , result);
			}
			else {
				printf("基于ECC算法的数字信封转换成功: \n");
				PrintData("转换后密文为", eccEnc2, 300, 16);
			}
			break;
		}
		case 9: {

			void* hKeyHandle = NULL;
			unsigned char ucKey[4096] = { 0 };
			unsigned int ucKeyLen;
			int result = SDF_GenerateKeyWithKEK(hSessionHandle, 128, SGD_SMS4_ECB, keyIndex, ucKey,&ucKeyLen, &hKeyHandle);
			if (result != 0) {
				printf("生成会话密钥并用密钥加密密钥加密输出失败: %08x\n" , result);
			}
			else {
				printf("生成会话密钥并用密钥加密密钥加密输出成功\n");
				PrintData("加密后密钥为", ucKey, ucKeyLen, 16);
			}
			break;
		}
		case 10: {
			void* hKeyHandle = NULL;
			unsigned char ucKey[4096] = { 0 };
			unsigned int ucKeyLen;
			int result = SDF_GenerateKeyWithKEK(hSessionHandle, 128, SGD_SMS4_ECB, keyIndex, ucKey, &ucKeyLen, &hKeyHandle);
			if (result != 0) {
				printf("生成会话密钥并用密钥加密密钥加密输出失败: %08x\n" , result);
			}
			else {
				printf("生成会话密钥并用密钥加密密钥加密输出成功\n");
				PrintData("加密后密钥为", ucKey, ucKeyLen, 16);
			}

			result = SDF_ImportKeyWithKEK(hSessionHandle, SGD_SMS4_ECB, keyIndex, ucKey, ucKeyLen, &hKeyHandle);
			if (result != 0) {
				printf("导入会话密钥并用密钥加密密钥解密失败: %08x\n" , result);
			}
			else {
				printf("导入会话密钥并用密钥加密密钥解密成功 \n");
			}
			break;
		}
		case 0:
		{
			rt = true;
			break;
		}
		default:
			printf("err input.\n");
			break;
		}

		if (rt)
			break;
	}

	// 释放权限
    rn = SDF_ReleasePrivateKeyAccessRight(hSessionHandle, keyIndex);
    if (rn != 0) {
        printf("释放私钥访问权限失败 %08x\n", rn);
    }
    else {
        printf("私钥访问权限已释放\n");
    }

	rn = SDF_CloseSession(hSessionHandle);
	if (rn == 0) {
		printf("关闭会话成功\n");
	}
	else {
		printf("关闭会话失败\n");
	}

	rn = SDF_CloseDevice(hDeviceHandle);
	if (rn == 0) {
		printf("关闭设备成功\n");
	}
	else {
		printf("关闭设备失败\n");
	}
	printf("\n");
}

// 密钥协商测试
void AgreementTest() {
	int rt = 0;
	void *hDeviceHandle = NULL;
	void *hSessionHandle = NULL;

	int rn = SDF_OpenDevice(&hDeviceHandle);
	if (rn == 0) {
		printf("打开设备成功\n");
	}
	else {
		printf("打开设备失败\n");
		return;
	}

	rn = SDF_OpenSession(hDeviceHandle, &hSessionHandle);
	if (rn == 0) {
		printf("打开会话成功\n");
	}
	else {
		printf("打开会话失败\n");
		return;
	}

	// 获取私钥访问权限
	rn = SDF_GetPrivateKeyAccessRight(hSessionHandle, 1, (unsigned char *)puiKeypasswd, 8);
	if (rn != 0) {
		printf("获取私钥访问权限失败 %08x\n", rn);
	}
	else {
		printf ("获取私钥访问权限成功\n");
	}

	while (true)
	{
		printf("<-----------------------密钥协商------------------------->\n");
		printf(" 1|密钥协商测试\n");
		printf(" 0|return\n");
		printf("<----------------------------------------------------->\n");
		printf("请输入测试功能编号：");

		int choice;
		scanf("%d", &choice);

		switch (choice)
		{
		case 1: {
			const char* sponsorID = "sponsor";//发起方id
			const char* responseID = "response";//响应方id

			//发起方
			ECCrefPublicKey pucSponsorPublicKey;
			ECCrefPublicKey pucSponsorTmpPublicKey;
			void* phAgreementHandle = NULL;
			void* phKeyHandle1 = NULL;
			
			int result = SDF_GenerateAgreementDataWithECC(hSessionHandle, 1, 128,
				(unsigned char*)sponsorID, strlen(sponsorID), &pucSponsorPublicKey,
				&pucSponsorTmpPublicKey, &phAgreementHandle);
			if (result == 0) {
				printf("生产密钥协商参数并输出成功!\n");
			}
			else {
				printf("生产密钥协商参数并输出失败! %08x\n" , result);
				return;
			}


			//响应方
			ECCrefPublicKey pucResponsePublicKey ;
			ECCrefPublicKey pucResponseTmpPublicKey ;
			void* phKeyHandle2 = NULL;
			result = SDF_GenerateAgreementDataAndKeyWithECC(hSessionHandle, 1, 128,
				(unsigned char*)responseID, strlen(responseID), (unsigned char*)sponsorID, strlen(sponsorID), &pucSponsorPublicKey, &pucSponsorTmpPublicKey,
				&pucResponsePublicKey, &pucResponseTmpPublicKey, &phKeyHandle2);

			if (result == 0) {
				printf("生产密钥协商参数并输出成功!");
			}
			else {
				printf("生产密钥协商参数并输出失败! %08x\n" , result);
				return;
			}


			//发起方
			result = SDF_GenerateKeyWithECC(hSessionHandle,
				(unsigned char*)responseID, strlen(responseID),
				&pucResponsePublicKey,
				&pucResponseTmpPublicKey,
				phAgreementHandle,
				&phKeyHandle1);
			if (result == 0) {
				printf("计算发起方会话密钥成功!\n");
			}
			else {
				printf("计算发起方会话密钥失败!%08x\n" , result);
				return;
			}

			//phKeyHandle1和phKeyHandle2为协商完成的密钥句柄，他们的密钥应该一致，使用加密算法对相同的数据加密密文应该一致，下面进行验证。
			unsigned char plain[32] = {0};
			unsigned int plainLen = 32;
			unsigned char iv[16] = {0};
			unsigned char encData[256] = { 0 };
			unsigned int encDataLen = 32;

			SDF_GenerateRandom(hSessionHandle, plainLen, plain);
			PrintData("原文", plain, plainLen, 16);

			//加密
			int ret = SDF_Encrypt(hSessionHandle, phKeyHandle1, SGD_SMS4_CBC, iv, plain, plainLen, encData,&encDataLen);
			if (ret != 0) {
				printf("加密失败: %08x", ret);
			}
			else {
				PrintData("密文", encData, encDataLen, 16);
			}

			// 加密2
			ret = SDF_Encrypt(hSessionHandle, phKeyHandle2, SGD_SMS4_CBC, iv, plain, plainLen, encData, &encDataLen);
			if (ret != 0) {
				printf("加密失败: %08x", ret);
			}
			else {
				PrintData("密文", encData, encDataLen, 16);
			}

		}
		case 0:
		{
			rt = true;
			break;
		}
		default:
			printf("err input.\n");
			break;
		}

		if (rt)
			break;

	}

	rn = SDF_ReleasePrivateKeyAccessRight(hSessionHandle, 1);
	if (rn != 0) {
		printf("释放私钥访问权限失败 %08x\n", rn);
	}
	else {
		printf("私钥访问权限已释放\n");
	}


	rn = SDF_CloseSession(hSessionHandle);
	if (rn == 0) {
		printf("关闭会话成功\n");
	}
	else {
		printf("关闭会话失败\n");
	}

	rn = SDF_CloseDevice(hDeviceHandle);
	if (rn == 0) {
		printf("关闭设备成功\n");
	}
	else {
		printf("关闭设备失败\n");
	}
	printf("\n");
}

// 非对称加密功能测试
void AsymKeyFuncTest() {
	int rt = 0;
	int result = 0;
	void *hDeviceHandle = NULL;
	void *hSessionHandle = NULL;

	int rn = SDF_OpenDevice(&hDeviceHandle);
	if (rn == 0) {
		printf("打开设备成功\n");
	}
	else {
		printf("打开设备失败\n");
		return;
	}

	rn = SDF_OpenSession(hDeviceHandle, &hSessionHandle);
	if (rn == 0) {
		printf("打开会话成功\n");
	}
	else {
		printf("打开会话失败\n");
		return;
	}


	while (true)
	{
		printf("<-----------------------非对称算法------------------------->\n");
		printf(" 1|内部RSA运算\n");
		printf(" 2|外部RSA运算\n");
		printf(" 3|内部密钥ECC签名验签\n");
		printf(" 4|外部密钥ECC签名验签\n");
		printf(" 5|内部密钥ECC加密解密\n");
		printf(" 6|外部密钥ECC加密解密\n");
		printf(" 0|return\n");
		printf("<----------------------------------------------------->\n");
		printf("请输入测试功能编号：");

		int choice = 0;
		scanf("%d", &choice);

		switch (choice)
		{
		case 1: {
			printf("请输入密钥号:");
			int keyIndex = 0;
			scanf("%d", &keyIndex);

			unsigned char sig[128] = { 0 };
			unsigned char plainByte[128] = {0};
			unsigned int plainByteLen  = 128;
			unsigned char decByte[128] = { 0 };
			unsigned int decByteLen = 128;
			unsigned int sigLen;

			SDF_GenerateRandom(hSessionHandle, plainByteLen, plainByte);

			PrintData("原文", plainByte, plainByteLen, 16);

			result = SDF_GetPrivateKeyAccessRight(hSessionHandle, keyIndex, (unsigned char *)puiKeypasswd, 8);
			if (result != 0) {
				printf("获取私钥访问权限失败 %08x\n", result);
			}
			else {
				printf ("获取私钥访问权限成功\n");
			}

			result = SDF_InternalPrivateKeyOperation_RSA(hSessionHandle, keyIndex, plainByte, plainByteLen, sig,&sigLen);
			if (result != 0) {
				printf("内部RSA私钥运算失败: %08x\n" ,result);
			}
			else {
				PrintData("内部RSA私钥运算成功", sig, sigLen, 16);
			}

			result = SDF_InternalPublicKeyOperation_RSA(hSessionHandle, keyIndex, sig, sigLen, decByte,&decByteLen);
			if (result != 0) {
				printf("内部RSA公钥运算失败: %08x" ,result);
			}
			else {
				PrintData("内部RSA公钥运算成功", decByte, decByteLen, 16);
			}

			result = SDF_ReleasePrivateKeyAccessRight(hSessionHandle, keyIndex);
			if (result != 0) {
				printf("释放私钥访问权限失败 %08x\n", result);
			}
			else {
				printf("私钥访问权限已释放\n");
			}

			break;
		}
		case 2: {
			unsigned char sig[128] = { 0 };
			unsigned char plainByte[128] = { 0 };
			unsigned int plainByteLen = 128;
			unsigned char decByte[128] = { 0 };
			unsigned int decByteLen = 128;
			unsigned int sigLen;

			RSArefPublicKey pubk;
			RSArefPrivateKey prik;
			result = SDF_GenerateKeyPair_RSA(hSessionHandle, 1024, &pubk, &prik);
			if (result == 0) {
				printf("产生RSA密钥对成功\n");
				PrintData("公钥", (unsigned char*)&pubk, sizeof(RSArefPublicKey), 16);
			}
			else {
				printf("产生RSA密钥对失败: %08x\n" ,result);
			}

			SDF_GenerateRandom(hSessionHandle, plainByteLen, plainByte);
			PrintData("原文", plainByte, plainByteLen, 16);

			result = SDF_ExternalPrivateKeyOperation_RSA(hSessionHandle, &prik, plainByte, plainByteLen, sig, &sigLen);
			if (result != 0) {
				printf("外部RSA私钥运算失败: %08x\n" ,result);
			}
			else {
				PrintData("外部RSA私钥运算成功", sig, sigLen, 16);
			}

			result = SDF_ExternalPublicKeyOperation_RSA(hSessionHandle, &pubk, sig, sigLen, decByte, &decByteLen);
			if (result != 0) {
				printf("外部RSA公钥运算失败: %08x\n" ,result);
			}
			else {
				PrintData("外部RSA公钥运算成功", decByte, decByteLen, 16);
			}
			break;
		}
		case 3: {
			printf("请输入密钥号:");
			int keyIndex;
			scanf("%d",&keyIndex);

			unsigned char hashByte[32] = {0};
			ECCSignature sig;

			result = SDF_GetPrivateKeyAccessRight(hSessionHandle, keyIndex, (unsigned char *)puiKeypasswd, 8);
			if (result != 0) {
				printf("获取私钥访问权限失败 %08x\n", result);
			}
			else {
				printf ("获取私钥访问权限成功\n");
			}

			result = SDF_InternalSign_ECC(hSessionHandle, keyIndex, hashByte,32, &sig);
			if (result != 0) {
				printf("内部密钥ECC签名失败: %08x\n" ,result);
			}
			else {
				PrintData("内部密钥ECC签名成功", (unsigned char*)&sig, sizeof(ECCSignature), 16);
			}

			result = SDF_InternalVerify_ECC(hSessionHandle, keyIndex, hashByte,32, &sig);
			if (result != 0) {
				printf("内部密钥ECC验签失败: %08x\n" ,result);
			}
			else {
				printf("内部密钥ECC验签成功: ");
			}

			result = SDF_ReleasePrivateKeyAccessRight(hSessionHandle, keyIndex);
			if (result != 0) {
				printf("释放私钥访问权限失败 %08x\n", result);
			}
			else {
				printf("私钥访问权限已释放\n");
			}


			break;
		}
		case 4: {
			unsigned char hashByte[32] = { 0 };
			ECCSignature sig;

			ECCrefPublicKey pubk ;
			ECCrefPrivateKey prik;
			result = SDF_GenerateKeyPair_ECC(hSessionHandle, SGD_SM2_1, 256, &pubk, &prik);
			printf("SDF_GenerateKeyPair_ECC: %08x\n" , result);
			if (result == 0) {
				printf("产生ECC密钥对成功\n");
				PrintData("公钥", (unsigned char*)&pubk, sizeof(ECCrefPublicKey), 16);
				PrintData("私钥", (unsigned char*)&prik, sizeof(ECCrefPrivateKey), 16);
			}
			else {
				printf("产生ECC密钥对失败: %08x\n" ,result);
			}

			result = SDF_ExternalSign_ECC(hSessionHandle,SGD_SM2_1, &prik, hashByte,32, &sig);
			if (result != 0) {
				printf("外部密钥ECC签名失败: %08x\n" ,result);
			}
			else {
				PrintData("外部密钥ECC签名成功", (unsigned char*)&sig, sizeof(ECCSignature), 16);
			}

			result = SDF_ExternalVerify_ECC(hSessionHandle, SGD_SM2_1, &pubk, hashByte,32, &sig);
			if (result != 0) {
				printf("外部密钥ECC验签失败: %08x\n" ,result);
			}
			else {
				printf("外部密钥ECC验签成功\n");
			}
			break;
		}
		case 5: {
			printf("请输入密钥号:");
			int keyIndex;
			scanf("%d", &keyIndex);

			unsigned char hashByte[32] = { 0 };
			SDF_GenerateRandom(hSessionHandle, 32, hashByte);
			PrintData("原文", hashByte, 32, 16);

			result = SDF_GetPrivateKeyAccessRight(hSessionHandle, keyIndex, (unsigned char *)puiKeypasswd, 8);
			if (result != 0) {
				printf("获取私钥访问权限失败 %08x\n", result);
			}
			else {
				printf ("获取私钥访问权限成功\n");
			}

			unsigned char enc[1024] = { 0 };
			result = SDF_InternalEncrypt_ECC(hSessionHandle, keyIndex, hashByte,32, (ECCCipher*)enc);
			if (result != 0) {
				printf("内部密钥ECC加密失败: %08x\n" ,result);
			}
			else {
				PrintData("内部密钥ECC加密成功", (unsigned char*)enc, 300, 16);
			}

			ECCrefPublicKey pubk;

			result = SDF_ExportEncPublicKey_ECC(hSessionHandle, keyIndex, &pubk);
			if (result != 0) {
				printf("导出ECC加密公钥失败: %08x\n" ,result);
			}
			else {
				PrintData("导出ECC加密公钥成功", (unsigned char*)&pubk, sizeof(ECCrefPublicKey), 16);

			}

			unsigned char enc2[1024] = { 0 };
			result = SDF_ExternalEncrypt_ECC(hSessionHandle, SGD_SM2_3, &pubk, hashByte,32, (ECCCipher*)enc2);
			if (result != 0) {
				printf("外部密钥ECC加密失败: %08x\n" ,result);
			}
			else {
				PrintData("外部密钥ECC加密成功", (unsigned char*)enc2, 300, 16);
			}

			unsigned char dec[1024] = { 0 };
			unsigned int decLen = 0;
			result = SDF_InternalDecrypt_ECC(hSessionHandle, keyIndex, (ECCCipher*)enc2, dec,&decLen);
			if (result != 0) {
				printf("内部密钥ECC解密失败: %08x\n" ,result);
			}
			else {
				PrintData("内部密钥ECC解密成功", dec, decLen, 16);
			}

			result = SDF_ReleasePrivateKeyAccessRight(hSessionHandle, keyIndex);
			if (result != 0) {
				printf("释放私钥访问权限失败 %08x\n", result);
			}
			else {
				printf("私钥访问权限已释放\n");
			}


			break;
		}
		case 6: {
			unsigned char hashByte[32] = { 0 };
			SDF_GenerateRandom(hSessionHandle, 32, hashByte);

			ECCrefPublicKey pubk;
			ECCrefPrivateKey prik;
			result = SDF_GenerateKeyPair_ECC(hSessionHandle, SGD_SM2_1, 256, &pubk, &prik);
			if (result == 0) {
				printf("产生ECC密钥对成功\n");
				PrintData("公钥", (unsigned char*)&pubk, sizeof(ECCrefPublicKey), 16);
				PrintData("私钥", (unsigned char*)&prik, sizeof(ECCrefPrivateKey), 16);
			}
			else {
				printf("产生ECC密钥对失败: %08x\n", result);
			}

			PrintData("原文", hashByte, 32, 16);

			unsigned char enc[1024] = {0};
			result = SDF_ExternalEncrypt_ECC(hSessionHandle, SGD_SM2_3, &pubk, hashByte,32, (ECCCipher*)enc);
			if (result != 0) {
				printf("外部密钥ECC加密失败: %08x" ,result);
			}
			else {
				PrintData("外部密钥ECC加密成功", (unsigned char*)enc, 292, 16);
			}

			unsigned char dec[1024] = { 0 };
			unsigned int decLen = 0;
			result = SDF_ExternalDecrypt_ECC(hSessionHandle, SGD_SM2_3, &prik, (ECCCipher*)enc, dec,&decLen);
			if (result != 0) {
				printf("外部密钥ECC解密失败: %08x" ,result);
			}
			else {
				PrintData("外部密钥ECC加密成功", (unsigned char*)dec, decLen, 16);
			}
			break;
		}
		case 0:
		{
			rt = true;
			break;
		}
		default:
			printf("err input.\n");
			break;
		}

		if (rt)
			break;
	}



	rn = SDF_CloseSession(hSessionHandle);
	if (rn == 0) {
		printf("关闭会话成功\n");
	}
	else {
		printf("关闭会话失败\n");
	}

	rn = SDF_CloseDevice(hDeviceHandle);
	if (rn == 0) {
		printf("关闭设备成功\n");
	}
	else {
		printf("关闭设备失败\n");
	}
	printf("\n");
}

// 对称加解密功能测试
void SymKeyFuncTest() {
	int rt = 0;
	void *hDeviceHandle = NULL;
	void *hSessionHandle = NULL;

	int rn = SDF_OpenDevice(&hDeviceHandle);
	if (rn == 0) {
		printf("打开设备成功\n");
	}
	else {
		printf("打开设备失败\n");
		return;
	}

	rn = SDF_OpenSession(hDeviceHandle, &hSessionHandle);
	if (rn == 0) {
		printf("打开会话成功\n");
	}
	else {
		printf("打开会话失败\n");
		return;
	}


	while (true)
	{
		printf("<-----------------------对称算法------------------------->\n");
		printf(" 1|对称加密解密\n");
		printf(" 2|计算MAC\n");
		printf(" 0|return\n");
		printf("<----------------------------------------------------->\n");
		printf("请输入测试功能编号：");

		int choice = 0;
		scanf("%d", &choice);

		switch (choice)
		{
		case 1: {
			unsigned char plain[128] = {0};
			unsigned int plainLen = 128;
			unsigned char enc[256] = { 0 };
			unsigned int encLen = 256;
			unsigned char dec[128] = { 0 };
			unsigned int decLen = 128;

			unsigned char iv[16] = { 0 };
			unsigned char keybyte[16] = { 0 };

			SDF_GenerateRandom(hSessionHandle, plainLen, plain);
			SDF_GenerateRandom(hSessionHandle, 16, keybyte);
			SDF_GenerateRandom(hSessionHandle, 16, iv);
			
			void* phKeyHandle = NULL;
			int ret = SDF_ImportKey(hSessionHandle, keybyte,16, &phKeyHandle);
			if (ret != 0) {
				printf("导入明文会话密钥失败 %08x\n", ret);
			}

			PrintData("原文", plain, plainLen, 16);

			ret = SDF_Encrypt(hSessionHandle, phKeyHandle,SGD_SMS4_CBC, iv, plain, plainLen,enc, &encLen);
			if (ret != 0) {
				printf("加密失败: %08x\n",ret);
			}
			else {
				PrintData("密文", enc, encLen, 16);
			}

			ret = SDF_Decrypt(hSessionHandle, phKeyHandle, SGD_SMS4_CBC, iv, enc,encLen, dec,&decLen);
			if (ret != 0) {
				printf("解密失败: %08x\n" ,ret);
			}
			else {
				PrintData("解密", dec, decLen, 16);
			}

			break;
		}
		case 2: {
			unsigned char plain[128] = { 0 };
			unsigned int plainLen = 128;
			unsigned char enc[128] = { 0 };
			unsigned int encLen = 128;

			unsigned char iv[16] = { 0 };
			unsigned char keybyte[16] = { 0 };

			SDF_GenerateRandom(hSessionHandle, plainLen, plain);
			SDF_GenerateRandom(hSessionHandle, 16, keybyte);
			SDF_GenerateRandom(hSessionHandle, 16, iv);

			void* phKeyHandle = NULL;
			SDF_ImportKey(hSessionHandle, keybyte,16, &phKeyHandle);

			PrintData("原文", plain, plainLen, 16);

			int ret = SDF_CalculateMAC(hSessionHandle, phKeyHandle,SGD_SMS4_MAC, iv, plain,plainLen, enc,&encLen);
			if (ret != 0) {
				printf("计算MAC失败: %08x\n", ret);
			}
			else {
				PrintData("MAC", enc, encLen, 16);
			}

			break;
		}
		case 0:
		{
			rt = true;
			break;
		}
		default:
			printf("err input.\n");
			break;
		}

		if (rt)
			break;
	}



	rn = SDF_CloseSession(hSessionHandle);
	if (rn == 0) {
		printf("关闭会话成功\n");
	}
	else {
		printf("关闭会话失败\n");
	}

	rn = SDF_CloseDevice(hDeviceHandle);
	if (rn == 0) {
		printf("关闭设备成功\n");
	}
	else {
		printf("关闭设备失败\n");
	}
	printf("\n");
}


void HashTest() {
	int rt = 0;
	int result = 0;
	void *hDeviceHandle = NULL;
	void *hSessionHandle = NULL;

	int rn = SDF_OpenDevice(&hDeviceHandle);
	if (rn == 0) {
		printf("打开设备成功\n");
	}
	else {
		printf("打开设备失败\n");
		return;
	}

	rn = SDF_OpenSession(hDeviceHandle, &hSessionHandle);
	if (rn == 0) {
		printf("打开会话成功\n");
	}
	else {
		printf("打开会话失败\n");
		return;
	}


	while (true)
	{
		printf("<-----------------------杂凑算法------------------------->\n");
		printf(" 1|SM3算法测试\n");
		printf(" 2|SM3(带公钥)算法测试\n");
		printf(" 0|return\n");
		printf("<----------------------------------------------------->\n");
		printf("请输入测试功能编号：");
		int choice = 0;
		scanf("%d", &choice);

		switch (choice)
		{
		case 1: {
			unsigned char ucHash[64] = {0};
			unsigned int ucHashLen = 0;
			unsigned char plain[64] = {0};
			SDF_GenerateRandom(hSessionHandle, 64, plain);
			PrintData("原文: ", plain, 64, 16);

			result = SDF_HashInit(hSessionHandle, SGD_SM3, NULL, NULL,0);
			if (result != 0) {
				printf("Hash初始化异常, %08x\n" , result);
			}
			else {
				result = SDF_HashUpdate(hSessionHandle, plain, 64);
				if (result != 0) {
					printf("SDF_HashUpdate异常, %08x\n", result);
				}
				result = SDF_HashFinal(hSessionHandle, ucHash,&ucHashLen);
				if (result != 0) {
					printf("SDF_HashFinal异常, %08x\n", result);
				}
				else {
					PrintData("计算摘要成功", ucHash, ucHashLen, 16);
				}
			}
			break;
		}
		case 2: {
			unsigned char ucHash[64] = { 0 };
			unsigned int ucHashLen = 0;

			unsigned char plain[64] = {0};
			SDF_GenerateRandom(hSessionHandle, 64, plain);
			PrintData("原文: ", plain, 64, 16);

			ECCrefPublicKey pubk;
			result = SDF_ExportEncPublicKey_ECC(hSessionHandle, 1, &pubk);
			if (result != 0) {
				printf("导出ECC加密公钥失败: %08x\n", result);
			}
			else {
				PrintData("导出ECC加密公钥成功", (unsigned char*)&pubk, sizeof(ECCrefPublicKey), 16);

			}

			result = SDF_HashInit(hSessionHandle, SGD_SM3, &pubk, (unsigned char*)"12345678", 8);
			if (result != 0) {
				printf("Hash初始化异常, %08x\n", result);
			}
			else {
				result = SDF_HashUpdate(hSessionHandle, plain, 64);
				if (result != 0) {
					printf("SDF_HashUpdate异常, %08x\n", result);
				}
				result = SDF_HashFinal(hSessionHandle, ucHash, &ucHashLen);
				if (result != 0) {
					printf("SDF_HashFinal异常, %08x\n", result);
				}
				else {
					PrintData("计算摘要成功", ucHash, ucHashLen, 16);
				}
			}
			break;
		}
		case 0:
		{
			rt = true;
			break;
		}
		default:
			printf("err input.\n");
			break;
		}

		if (rt)
			break;

	}



	rn = SDF_CloseSession(hSessionHandle);
	if (rn == 0) {
		printf("关闭会话成功\n");
	}
	else {
		printf("关闭会话失败\n");
	}

	rn = SDF_CloseDevice(hDeviceHandle);
	if (rn == 0) {
		printf("关闭设备成功\n");
	}
	else {
		printf("关闭设备失败\n");
	}
	printf("\n");
}

void FileTest() {
	int result = 0;
	void *hDeviceHandle = NULL;
	void *hSessionHandle = NULL;

	int rn = SDF_OpenDevice(&hDeviceHandle);
	if (rn == 0) {
		printf("打开设备成功\n");
	}
	else {
		printf("打开设备失败\n");
		return;
	}

	rn = SDF_OpenSession(hDeviceHandle, &hSessionHandle);
	if (rn == 0) {
		printf("打开会话成功\n");
	}
	else {
		printf("打开会话失败\n");
		return;
	}


	result = SDF_CreateFile(hSessionHandle, (unsigned char*)"test_sdf", strlen("test_sdf"), 1024);
	if (result == 0) {
		printf("创建文件成功!");
	}
	else {
		printf("创建文件失败! %08x\n",result);
	}

	result = SDF_WriteFile(hSessionHandle, (unsigned char*)"test_sdf", strlen("test_sdf"), 0, strlen("hello"), (unsigned char*)"hello");
	if (result == 0) {
		printf("写文件成功!");
	}
	else {
		printf("写文件失败!%08x\n",result);
		return;
	}

	unsigned char outBuf[2048] = {0};
	unsigned int outLen = 5;
	result = SDF_ReadFile(hSessionHandle, (unsigned char*)"test_sdf", strlen("test_sdf"), 0, &outLen, outBuf);
	if (result == 0) {
		printf("读文件成功! %s \n" , outBuf);
	}
	else {
		printf("读文件失败!%08x\n", result);
		return;
	}

	result = SDF_DeleteFile(hSessionHandle, (unsigned char*)"test_sdf", strlen("test_sdf"));
	if (result == 0) {
		printf("删除文件成功!\n");
	}
	else {
		printf("删除文件失败!%08x\n", result);
		return;
	}


	rn = SDF_CloseSession(hSessionHandle);
	if (rn == 0) {
		printf("关闭会话成功\n");
	}
	else {
		printf("关闭会话失败\n");
	}

	rn = SDF_CloseDevice(hDeviceHandle);
	if (rn == 0) {
		printf("关闭设备成功\n");
	}
	else {
		printf("关闭设备失败\n");
	}
	printf("\n");
}


void PQCFuncTest() {
	int result = 0;
	void *hDeviceHandle = NULL;
	void *hSessionHandle = NULL;

	int rn = SDF_OpenDevice(&hDeviceHandle);
	if (rn == 0) {
		printf("打开设备成功\n");
	}
	else {
		printf("打开设备失败\n");
		return;
	}

	rn = SDF_OpenSession(hDeviceHandle, &hSessionHandle);
	if (rn == 0) {
		printf("打开会话成功\n");
	}
	else {
		printf("打开会话失败\n");
		return;
	}

	int ret = 0;
	while (true) {
		printf("<-----------------------后量子算法------------------------->\n");
		printf(" 1|密钥协商算法测试\n");
		printf(" 2|签名验签算法测试\n");
		printf(" 0|return\n");
		printf("<----------------------------------------------------->\n");
		printf("请输入测试功能编号：");

		int choice = 0;
		scanf("%d", &choice);
		switch(choice)
		{
		case 1: {
			unsigned char pubKey[10240] = {0};
			int pubKeyLen = sizeof(pubKey);
			unsigned char priKey[10240] = {0};
			int priKeyLen = sizeof(priKey);

    		int ret = SDF_PQC_KemKeypair(PQC_KEM_BIKE_L1, pubKey, &pubKeyLen, priKey, &priKeyLen);
			if (ret != 0) {
				printf("生成KEM密钥对失败 %08x\n", ret);

			}
			else {
				printf("生成KEM密钥对成功\n");
				PrintData("KEM_PUBLICKEY", pubKey, pubKeyLen, 16);
				PrintData("KEM_PRIVATEKEY", priKey, priKeyLen, 16);
			}

			unsigned char sharedSecret[1024] = {0};
			int shareLen = sizeof(sharedSecret);

			unsigned char cipherText[4906] = {0};
			int cipherLen = sizeof(cipherText);

			unsigned char sharedSecret2[1024] = {0};
			int shareLen2 = sizeof(sharedSecret2);


			ret = SDF_PQC_KemEncaps(PQC_KEM_BIKE_L1, pubKey, pubKeyLen, sharedSecret, &shareLen, cipherText, &cipherLen);
			if (ret != 0) {
				printf("生成共享密钥和共享密文失败 %08x\n", ret);
			}
			else {
				printf("生成共享密钥和共享密文成功\n");
				PrintData("共享密钥", sharedSecret, shareLen, 16);
				PrintData("共享密文", cipherText, cipherLen, 16);
			}



			ret = SDF_PQC_KemDecaps(PQC_KEM_BIKE_L1, cipherText, cipherLen, priKey, priKeyLen, sharedSecret2, &shareLen2);
			if (ret != 0) {
				printf("私钥解密共享密文获得共享密钥失败 %08x\n", ret);
			}
			else {
				printf("私钥解密共享密文获得共享密钥成功\n");
				PrintData("解密共享密钥", sharedSecret2, shareLen2, 16);
			}
			break;

		}
		case 2: {
			unsigned char pubKey[1024] = {0};
			int pubKeyLen = sizeof(pubKey);
			unsigned char priKey[1024] = {0};
			int priKeyLen = sizeof(priKey);

			result = SDF_PQC_SigKeypair(PQC_SIG_SPHINCS_SHA2_128F_SIMPLE, pubKey, &pubKeyLen, priKey, &priKeyLen);
			if (result != 0) {
				printf("生成签名算法密钥对失败 %08x\n", result);
				break;
			}
			else {
				printf("生成签名算法密钥对成功\n");
				PrintData("Sig_PUBLICKEY", pubKey, pubKeyLen, 16);
				PrintData("Sig_PRIVATEKEY", priKey, priKeyLen, 16);

			}
			unsigned char msg[128] = {0};
			int msgLen = sizeof(msg);
			SDF_GenerateRandom(hSessionHandle, msgLen, msg);

			unsigned char sign[20480] = {0};
			int signLen = sizeof(sign);

			result = SDF_PQC_SigSign(PQC_SIG_SPHINCS_SHA2_128F_SIMPLE, priKey, priKeyLen, msg, msgLen, sign, &signLen);
			if (result != 0) {
				printf("签名失败: %08x\n", result);
				break;
			}
			else {
				printf("签名成功\n");
				PrintData("签名结果", sign, signLen, 16);
			}

			result = SDF_PQC_SigVerify(PQC_SIG_SPHINCS_SHA2_128F_SIMPLE, msg, msgLen, sign, signLen, pubKey, pubKeyLen);
			if (result != 0) {
				printf("公钥验签失败: %08x\n", result);
				break;
			}
			else {
				printf("公钥验签成功\n");
			}
			break;
			
		}

		case 0: {
			ret = 1;
			break;
		}
		default: 
			printf("err input.\n");
			break;
		}
		
		if(ret == 1) {
			break;
		}
	}

	rn = SDF_CloseSession(hSessionHandle);
	if (rn == 0) {
		printf("关闭会话成功\n");
	}
	else {
		printf("关闭会话失败\n");
	}

	rn = SDF_CloseDevice(hDeviceHandle);
	if (rn == 0) {
		printf("关闭设备成功\n");
	}
	else {
		printf("关闭设备失败\n");
	}
	printf("\n");
}


int main(int argc, char **argv) {
	if (argc != 6) {
		printf("a.out [IP] [port] [appName] [appPIN] [puiKeyPasswd].\n");
		return -1;
	}
	const char *ip = argv[1];
    const char *port = argv[2];
    const char *appName = argv[3];
    const char *appPin = argv[4];
	puiKeypasswd = argv[5];

	int rn = SDF_Initialize(ip, port, appName, appPin);
	if (rn == 0) {
		printf("连接成功\n");
	}
	else {
		printf("连接失败 %d\n", rn);
	}
	printf("##################### 密码机功能测试 #####################\n");
	printf("######## 输入功能前的编号测试对应功能,输入 0 返回 ########\n");
	while (true)
	{
		int rt = 0;
		int choice;
		printf("<-----------------------功能测试------------------------->\n");
		printf(" 1|设备管理函数测试\n");
		printf(" 2|非对称密钥管理\n");
		printf(" 3|会话密钥管理\n");
		printf(" 4|密钥协商\n");
		printf(" 5|非对称算法测试\n");
		printf(" 6|对称算法测试\n");
		printf(" 7|杂凑算法测试\n");
		printf(" 8|文件操作\n");
		printf(" 9|后量子算法测试\n");

		printf(" 0|exit\n");
		printf("<----------------------------------------------------->\n");
		printf("请输入测试功能编号：");
		scanf("%d", &choice);

		switch (choice)
		{
		case 1:
			DeviceMgrFuncTest();
			break;
		case 2:
			AsymKeyMgrFuncTest();
			break;
		case 3:
			SymKeyMgrFuncTest();
			break;
		case 4:
			AgreementTest();
			break;
		case 5:
			AsymKeyFuncTest();
			break;
		case 6:
			SymKeyFuncTest();
			break;
		case 7:
			HashTest();
			break;
		case 8:
			FileTest();
			break;
		case 9:
			PQCFuncTest();
			break;
		case 0:
			rt = 1;
			break;

		default:
			printf("err input.\n");
			break;
		}

		if (rt)
			break;
	}

	return 0;
}
